package com.pay.service.impl;

import com.pay.config.wxpay.MyConfig;
import com.pay.config.wxpay.WXPay;
import com.pay.config.wxpay.WXPayConstants;
import com.pay.config.wxpay.WXPayUtil;
import com.pay.model.interface_return.WxPayAuthCodeReturn;
import com.pay.model.interface_return.WxPayMobileWebReturn;
import com.pay.model.interface_return.WxPayQrCodeReturn;
import com.pay.model.interface_return.WxPayRefundReturn;
import com.pay.service.inter.WeixinpayService;
import com.pay.utils.CodeEnum;
import com.pay.utils.Utils;
import com.pay.utils.validate.vali_util.ValidateUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * 微信支付
 *
 * @author MENG
 * @version 2018/7/11
 * @see
 */
@Service("weixinpayService")
public class WeixinpayServiceImpl implements WeixinpayService
{

    Logger logger = LoggerFactory.getLogger(WeixinpayServiceImpl.class);

    public Map<String,Object> scanPay(String appId, String mchId, String apiKey, String notifyUrl,String outTradeNo, String totalAmount, String subject,String qrpayouttime)
    {
        //根据outtime 实时计算失效时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

        Date now = new Date();


        long nowtime = now.getTime() + (Integer.valueOf(qrpayouttime)*1000*60);

        String outTimeDateStr = simpleDateFormat.format(new Date(nowtime));

        //返回结果
        WxPayQrCodeReturn wxPayQrCodeReturn = new WxPayQrCodeReturn();

        //订单号
        wxPayQrCodeReturn.setOrderNo(outTradeNo);

        //订单金额
        wxPayQrCodeReturn.setTotalAmount(totalAmount);

        //订单二维码失效时间
        wxPayQrCodeReturn.setQrCodeTimeoutExpress(qrpayouttime);

        //设置配置
        MyConfig config = new MyConfig();

        config.setApiKey(apiKey);

        config.setAppId(appId);

        config.setMchId(mchId);

        try
        {
            WXPay wxpay = new WXPay(config);

            Map<String, String> data = new HashMap<String, String>();

            data.put("body", subject);

            data.put("out_trade_no", outTradeNo);

            data.put("fee_type", "CNY");

            data.put("time_expire", outTimeDateStr);

            BigDecimal totalFee = BigDecimal.valueOf(0);

            if(totalAmount != null && !"".equals(totalAmount))
            {
                //单位默认为分  *100
                totalFee = BigDecimal.valueOf(Double.valueOf(totalAmount)).multiply(BigDecimal.valueOf(100));
            }

            data.put("total_fee", String.valueOf(totalFee.intValue()));

            data.put("spbill_create_ip", Utils.getServerIp());

            logger.info("当前服务器IP：" + Utils.getServerIp());

            data.put("notify_url", notifyUrl);

            data.put("trade_type", "NATIVE");  // 此处指定为扫码支付

            //执行调用支付api
            Map<String, String> resp = wxpay.unifiedOrder(data);

            String returnCode = resp.get("return_code");

            if("SUCCESS".equals(returnCode))
            {
                String resultCode = resp.get("result_code");

                if("SUCCESS".equals(resultCode))
                {
                    String content = resp.get("code_url");

                    wxPayQrCodeReturn.setQrCodeContent(content);

                    return ValidateUtil.returnSuccess(wxPayQrCodeReturn);
                }
                else
                {
                    logger.error("微信扫码支付订单创建失败");

                    String errMsg = resp.get("err_code_des");

                    String errCode = resp.get("err_code");

                    logger.error("ERROR_CODE ："+ errCode + "、ERROR_MSG ：" + errMsg);

                    return ValidateUtil.returnError(CodeEnum.WXPAY_TRADE_PRECREATE_FAILE.getCode(),CodeEnum.WXPAY_TRADE_PRECREATE_FAILE.getMessage());
                }
            }
            else
            {
                logger.error("微信扫码支付API调用失败");

                String errMsg = resp.get("return_msg");

                logger.error("ERROR_MSG ：" + errMsg);

                return ValidateUtil.returnError(CodeEnum.INVOKE_WXPAY_TRADE_PRECREATE_FAILE.getCode(),CodeEnum.INVOKE_WXPAY_TRADE_PRECREATE_FAILE.getMessage());
            }
        }
        catch (Exception e)
        {
            logger.error("微信扫码支付执行错误!",e);

            return ValidateUtil.returnError(CodeEnum.WXPAY_TRADE_PRECREATE_ERROR.getCode(),CodeEnum.WXPAY_TRADE_PRECREATE_ERROR.getMessage());
        }
    }


    @Override
    public Map<String, Object> wxPayMobileWeb(String appId, String mchId, String apiKey,
                                              String notifyUrl, String orderNo, String totalAmount,
                                              String subject, String timeoutExpress,
                                              String sceneInfo)
    {
        //根据outtime 实时计算失效时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

        Date now = new Date();

        BigDecimal minute = (new BigDecimal(1000).multiply(new BigDecimal(60)));

        BigDecimal nowTime = new BigDecimal(now.getTime()).add(new BigDecimal(Integer.valueOf(timeoutExpress)).multiply(minute));

        String outTimeDateStr = simpleDateFormat.format(new Date(Long.valueOf(nowTime.toString())));

        //返回结果
        WxPayMobileWebReturn wxPayMobileWebReturn = new WxPayMobileWebReturn();

        //订单号
        wxPayMobileWebReturn.setOrderNo(orderNo);

        //订单金额
        wxPayMobileWebReturn.setTotalAmount(totalAmount);

        //订单二维码失效时间
        wxPayMobileWebReturn.setTimeoutExpress(timeoutExpress);

        //设置配置
        MyConfig config = new MyConfig();

        config.setApiKey(apiKey);

        config.setAppId(appId);

        config.setMchId(mchId);

        try
        {
            WXPay wxpay = new WXPay(config);

            Map<String, String> data = new HashMap<String, String>();

            data.put("body", subject);

            data.put("out_trade_no", orderNo);

            data.put("fee_type", "CNY");

            data.put("time_expire", outTimeDateStr);

            BigDecimal totalFee = BigDecimal.valueOf(0);

            if(totalAmount != null && !"".equals(totalAmount))
            {
                //单位默认为分  *100
                totalFee = BigDecimal.valueOf(Double.valueOf(totalAmount)).multiply(BigDecimal.valueOf(100));
            }

            data.put("total_fee", String.valueOf(totalFee.intValue()));

            data.put("spbill_create_ip", Utils.getServerIp());

            logger.info("当前服务器IP：" + Utils.getServerIp());

            data.put("notify_url", notifyUrl);

            data.put("trade_type", "MWEB");  // H5

            data.put("scene_info",sceneInfo);

            //执行调用支付api
            Map<String, String> resp = wxpay.unifiedOrder(data);

            String returnCode = resp.get("return_code");

            if("SUCCESS".equals(returnCode))
            {
                String resultCode = resp.get("result_code");

                if("SUCCESS".equals(resultCode))
                {
                    String mWebUrl = resp.get("mweb_url");

                    String prepayId = resp.get("prepay_id");

                    String appIdReturn = resp.get("appid");

                    String nonceStr = resp.get("nonce_str");

                    String paySign = resp.get("sign");

                    wxPayMobileWebReturn.setmWebUrl(mWebUrl);

                    wxPayMobileWebReturn.setPrepayId(prepayId);

                    wxPayMobileWebReturn.setAppId(appIdReturn);

                    wxPayMobileWebReturn.setNonceStr(nonceStr);

                    wxPayMobileWebReturn.setPaySign(paySign);

                    wxPayMobileWebReturn.setTimeStamp(String.valueOf(new Date().getTime()/1000));

                    return ValidateUtil.returnSuccess(wxPayMobileWebReturn);
                }
                else
                {
                    logger.error("手机H5微信支付失败.");

                    String errMsg = resp.get("err_code_des");

                    String errCode = resp.get("err_code");

                    logger.error("ERROR_CODE ："+ errCode + "、ERROR_MSG ：" + errMsg);

                    return ValidateUtil.returnError(CodeEnum.WXPAY_WXPAY_MOBILE_WEB_FAILE.getCode(),CodeEnum.WXPAY_WXPAY_MOBILE_WEB_FAILE.getMessage());
                }
            }
            else
            {
                logger.error("调用手机H5微信支付API失败.");

                String errMsg = resp.get("return_msg");

                logger.error("ERROR_MSG ：" + errMsg);

                return ValidateUtil.returnError(CodeEnum.INVOKE_WXPAY_MOBILE_WEB_FAILE.getCode(),CodeEnum.INVOKE_WXPAY_MOBILE_WEB_FAILE.getMessage());
            }
        }
        catch (Exception e)
        {
            logger.error("手机H5微信支付错误!",e);

            return ValidateUtil.returnError(CodeEnum.WXPAY_WXPAY_MOBILE_WEB_ERROR.getCode(),CodeEnum.WXPAY_WXPAY_MOBILE_WEB_ERROR.getMessage());
        }
    }

    @Override
    public Map<String, Object> wxPayMobileWechatWeb(String appId, String mchId, String apiKey,
                                                    String notifyUrl, String orderNo,
                                                    String totalAmount, String subject,
                                                    String timeoutExpress, String sceneInfo,
                                                    String openId)
    {
        //根据outtime 实时计算失效时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

        Date now = new Date();

        BigDecimal minute = (new BigDecimal(1000).multiply(new BigDecimal(60)));

        BigDecimal nowTime = new BigDecimal(now.getTime()).add(new BigDecimal(Integer.valueOf(timeoutExpress)).multiply(minute));

        String outTimeDateStr = simpleDateFormat.format(new Date(Long.valueOf(nowTime.toString())));

        //返回结果
        WxPayMobileWebReturn wxPayMobileWebReturn = new WxPayMobileWebReturn();

        //订单号
        wxPayMobileWebReturn.setOrderNo(orderNo);

        //订单金额
        wxPayMobileWebReturn.setTotalAmount(totalAmount);

        //订单二维码失效时间
        wxPayMobileWebReturn.setTimeoutExpress(timeoutExpress);

        //设置配置
        MyConfig config = new MyConfig();

        config.setApiKey(apiKey);

        config.setAppId(appId);

        config.setMchId(mchId);

        try
        {
            WXPay wxpay = new WXPay(config);

            Map<String, String> data = new HashMap<String, String>();

            data.put("body", subject);

            data.put("out_trade_no", orderNo);

            data.put("fee_type", "CNY");

            data.put("time_expire", outTimeDateStr);

            BigDecimal totalFee = BigDecimal.valueOf(0);

            if(totalAmount != null && !"".equals(totalAmount))
            {
                //单位默认为分  *100
                totalFee = BigDecimal.valueOf(Double.valueOf(totalAmount)).multiply(BigDecimal.valueOf(100));
            }

            data.put("total_fee", String.valueOf(totalFee.intValue()));

            data.put("spbill_create_ip", Utils.getServerIp());

            logger.info("当前服务器IP：" + Utils.getServerIp());

            data.put("notify_url", notifyUrl);

            data.put("trade_type", "JSAPI");  // H5

            data.put("openid", openId);

            data.put("scene_info",sceneInfo);

            //执行调用支付api
            Map<String, String> resp = wxpay.unifiedOrder(data);

            String returnCode = resp.get("return_code");

            if("SUCCESS".equals(returnCode))
            {
                String resultCode = resp.get("result_code");

                if("SUCCESS".equals(resultCode))
                {
                    String mWebUrl = resp.get("mweb_url");

                    String prepayId = resp.get("prepay_id");

                    String appIdReturn = resp.get("appid");

                    String nonceStr = resp.get("nonce_str");

                    Map<String,String> paySignMap = new HashMap<>();

                    paySignMap.put("appId",appIdReturn);

                    String timeStamp = String.valueOf(new Date().getTime()/1000);
                    paySignMap.put("timeStamp",timeStamp);

                    paySignMap.put("nonceStr",nonceStr);

                    paySignMap.put("package","prepay_id="+prepayId);

                    paySignMap.put("signType", WXPayConstants.HMACSHA256);

                    wxPayMobileWebReturn.setmWebUrl(mWebUrl);

                    wxPayMobileWebReturn.setPrepayId(prepayId);

                    wxPayMobileWebReturn.setAppId(appIdReturn);

                    wxPayMobileWebReturn.setNonceStr(nonceStr);

                    wxPayMobileWebReturn.setPaySign(WXPayUtil.generateSignature(paySignMap, apiKey,
                            WXPayConstants.SignType.HMACSHA256));

                    wxPayMobileWebReturn.setTimeStamp(timeStamp);

                    return ValidateUtil.returnSuccess(wxPayMobileWebReturn);
                }
                else
                {
                    logger.error("手机H5微信支付失败.");

                    String errMsg = resp.get("err_code_des");

                    String errCode = resp.get("err_code");

                    logger.error("ERROR_CODE ："+ errCode + "、ERROR_MSG ：" + errMsg);

                    return ValidateUtil.returnError(CodeEnum.WXPAY_WXPAY_MOBILE_WEB_FAILE.getCode(),CodeEnum.WXPAY_WXPAY_MOBILE_WEB_FAILE.getMessage());
                }
            }
            else
            {
                logger.error("调用手机H5微信支付API失败.");

                String errMsg = resp.get("return_msg");

                logger.error("ERROR_MSG ：" + errMsg);

                return ValidateUtil.returnError(CodeEnum.INVOKE_WXPAY_MOBILE_WEB_FAILE.getCode(),CodeEnum.INVOKE_WXPAY_MOBILE_WEB_FAILE.getMessage());
            }
        }
        catch (Exception e)
        {
            logger.error("手机H5微信支付错误!",e);

            return ValidateUtil.returnError(CodeEnum.WXPAY_WXPAY_MOBILE_WEB_ERROR.getCode(),CodeEnum.WXPAY_WXPAY_MOBILE_WEB_ERROR.getMessage());
        }
    }

    @Override
    public Map<String,Object> weixinCode(String appId, String mchId, String apiKey, String notifyUrl,
                           String outTradeNo, String totalAmount, String subject,
                           String authCode,String qrpayouttime)
    {
//        https://api.mch.weixin.qq.com/pay/microPay

        //根据outtime 实时计算失效时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

        long oldTime = new Date().getTime();

        //设置 支付平台的订单最后付款时间
        long nowTime = oldTime + (Integer.valueOf(qrpayouttime))*1000*60;

        String outTimeDateStr = simpleDateFormat.format(new Date(nowTime));

        //返回结果
        WxPayAuthCodeReturn wxPayAuthCodeReturn = new WxPayAuthCodeReturn();

        //订单号
        wxPayAuthCodeReturn.setOrderNo(outTradeNo);

        //订单金额
        wxPayAuthCodeReturn.setTotalAmount(totalAmount);

        //订单最后支付时间
        wxPayAuthCodeReturn.setTimeoutExpress(qrpayouttime);

        //设置配置
        MyConfig config = new MyConfig();

        config.setApiKey(apiKey);

        config.setAppId(appId);

        config.setMchId(mchId);

        try
        {
            WXPay wxpay = new WXPay(config);

            Map<String, String> data = new HashMap<String, String>();

            data.put("body", subject);

            data.put("out_trade_no", outTradeNo);

            data.put("fee_type", "CNY");

            data.put("time_expire", outTimeDateStr);

            //单位默认为分  *100
            BigDecimal totalFee = BigDecimal.valueOf(Double.valueOf(totalAmount)).multiply(BigDecimal.valueOf(100));

            data.put("total_fee", String.valueOf(totalFee.intValue()));

            data.put("spbill_create_ip", Utils.getServerIp());

            logger.info("当前服务器IP：" + Utils.getServerIp());

            data.put("auth_code", authCode);

            Map<String, String> resp = wxpay.microPay(data);

            String returnCode = resp.get("return_code");

            if("SUCCESS".equals(returnCode))
            {
                String resultCode = resp.get("result_code");

                if("SUCCESS".equals(resultCode))
                {
                    wxPayAuthCodeReturn.setPayStatus("1");//支付成功

                    return ValidateUtil.returnSuccess(wxPayAuthCodeReturn);
                }
                else
                {
                    String errMsg = resp.get("err_code_des");

                    String errCode = resp.get("err_code");

                    if("USERPAYING".equals(errCode))
                    {
                        logger.info("微信付款码支付中.....");

                        wxPayAuthCodeReturn.setPayStatus("2");//支付中

                        return ValidateUtil.returnSuccess(wxPayAuthCodeReturn);
                    }
                    else
                    {
                        logger.error("微信付款码支付失败");

                        logger.error("ERROR_CODE ："+ errCode + "、ERROR_MSG ：" + errMsg);

                        return ValidateUtil.returnError(CodeEnum.WXPAY_TRADE_PAY_FAILE.getCode(),CodeEnum.WXPAY_TRADE_PAY_FAILE.getMessage());
                    }

                }
            }
            else
            {
                logger.error("微信付款码支付API调用失败");

                String errMsg = resp.get("return_msg");

                logger.error("ERROR_MSG ：" + errMsg);

                return ValidateUtil.returnError(CodeEnum.INVOKE_WXPAY_TRADE_PAY_FAILE.getCode(),CodeEnum.INVOKE_WXPAY_TRADE_PAY_FAILE.getMessage());
            }
        }
        catch (Exception e)
        {
            logger.error("微信付款码支付执行错误!",e);

            return ValidateUtil.returnError(CodeEnum.WXPAY_TRADE_PAY_ERROR.getCode(),CodeEnum.WXPAY_TRADE_PAY_ERROR.getMessage());
        }
    }


    private static int socketTimeout = 10000;// 连接超时时间，默认10秒
    private static int connectTimeout = 30000;// 传输超时时间，默认30秒
    private static RequestConfig requestConfig;// 请求器的配置

    @Override
    public Map<String, Object> weixinRefund(String appId, String mchId, String apiKey,
                                            String outTradeNo, String refundAmount,
                                            String refundReason)
    {
        //返回结果
        WxPayRefundReturn wxPayRefundReturn = new WxPayRefundReturn();

        //订单号
        wxPayRefundReturn.setOrderNo(outTradeNo);

        //退款金额
        wxPayRefundReturn.setRefundAmount(refundAmount);

        //退款原因
        wxPayRefundReturn.setRefundReason(refundReason);

        //设置配置
        MyConfig config = new MyConfig();

        config.setApiKey(apiKey);

        config.setAppId(appId);

        config.setMchId(mchId);

        try
        {
            WXPay wxpay = new WXPay(config,"");

            Map<String, String> data = new HashMap<String, String>();

            data.put("out_refund_no", outTradeNo);

            data.put("out_trade_no", outTradeNo);

            data.put("refund_fee_type", "CNY");

            //单位默认为分  *100
            BigDecimal totalFee = BigDecimal.valueOf(Double.valueOf(refundAmount)).multiply(BigDecimal.valueOf(100));

            data.put("total_fee", String.valueOf(totalFee.intValue()));

            data.put("refund_fee", String.valueOf(totalFee.intValue()));

            data.put("refund_desc", Utils.getServerIp());

            data.put("refund_desc", refundReason);

            Map<String, String> refundData = wxpay.fillRequestData(data);

            String xmlstr = Utils.mapToxml(refundData);

            CloseableHttpClient httpClient = initCert(mchId,"static/cert/apiclient_cert.p12");

            System.out.println("static/cert/apiclient_cert.p12");

            HttpPost httppost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");

            // 得指明使用UTF-8编码，否则到API服务器XML的中文不能被成功识别
            StringEntity postEntity = new StringEntity(xmlstr, "UTF-8");

            httppost.addHeader("Content-Type", "text/xml");

            httppost.setEntity(postEntity);

            requestConfig =  RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();

            // 设置请求器的配置
            httppost.setConfig(requestConfig);

            HttpResponse response = null;

            response = httpClient.execute(httppost);

            HttpEntity entity = response.getEntity();

            String result = EntityUtils.toString(entity, "UTF-8");

            Map<String,String> resp = Utils.xmlToMap(result);

            String returnCode = resp.get("return_code");

            if("SUCCESS".equals(returnCode))
            {
                String resultCode = resp.get("result_code");

                if("SUCCESS".equals(resultCode))
                {
                    return ValidateUtil.returnSuccess(wxPayRefundReturn);
                }
                else
                {
                    logger.error("微信支付退款失败");

                    String errMsg = resp.get("err_code_des");

                    String errCode = resp.get("err_code");

                    logger.error("ERROR_CODE ："+ errCode + "、ERROR_MSG ：" + errMsg);

                    return ValidateUtil.returnError(CodeEnum.WXPAY_TRADE_REFUND_FAILE.getCode(),CodeEnum.WXPAY_TRADE_REFUND_FAILE.getMessage());
                }
            }
            else
            {
                logger.error("微信支付退款API调用失败");

                String errMsg = resp.get("return_msg");

                logger.error("ERROR_MSG ：" + errMsg);

                return ValidateUtil.returnError(CodeEnum.INVOKE_WXPAY_TRADE_REFUND_FAILE.getCode(),CodeEnum.INVOKE_WXPAY_TRADE_REFUND_FAILE.getMessage());
            }
        }
        catch (Exception e)
        {
            logger.error("微信支付退款执行错误!",e);

            return ValidateUtil.returnError(CodeEnum.WXPAY_TRADE_REFUND_ERROR.getCode(),CodeEnum.WXPAY_TRADE_REFUND_ERROR.getMessage());
        }
    }


    @Override
    public Map<String, Object> wxPayRebate(String appId, String mchId, String apiKey,
                                            String outTradeNo, String refundAmount,
                                            String refundReason,String totalAmount,String sunOrderCode)
    {
        //返回结果
        WxPayRefundReturn wxPayRefundReturn = new WxPayRefundReturn();

        //订单号
        wxPayRefundReturn.setOrderNo(outTradeNo);

        //退款金额
        wxPayRefundReturn.setRefundAmount(refundAmount);

        //退款原因
        wxPayRefundReturn.setRefundReason(refundReason);

        //设置配置
        MyConfig config = new MyConfig();

        config.setApiKey(apiKey);

        config.setAppId(appId);

        config.setMchId(mchId);

        try
        {
            WXPay wxpay = new WXPay(config,"");

            Map<String, String> data = new HashMap<String, String>();

            data.put("out_refund_no", sunOrderCode);

            data.put("out_trade_no", outTradeNo);

            data.put("refund_fee_type", "CNY");

            //单位默认为分  *100
            BigDecimal totalFee = BigDecimal.valueOf(Double.valueOf(totalAmount)).multiply(BigDecimal.valueOf(100));

            BigDecimal refundFee = BigDecimal.valueOf(Double.valueOf(refundAmount)).multiply(BigDecimal.valueOf(100));

            data.put("total_fee", String.valueOf(totalFee.intValue()));

            data.put("refund_fee", String.valueOf(refundFee.intValue()));

            data.put("refund_desc", Utils.getServerIp());

            data.put("refund_desc", refundReason);

            Map<String, String> refundData = wxpay.fillRequestData(data);

            String xmlstr = Utils.mapToxml(refundData);

            CloseableHttpClient httpClient = initCert(mchId,"static/cert/apiclient_cert.p12");

            System.out.println("static/cert/apiclient_cert.p12");

            HttpPost httppost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");

            // 得指明使用UTF-8编码，否则到API服务器XML的中文不能被成功识别
            StringEntity postEntity = new StringEntity(xmlstr, "UTF-8");

            httppost.addHeader("Content-Type", "text/xml");

            httppost.setEntity(postEntity);

            requestConfig =  RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();

            // 设置请求器的配置
            httppost.setConfig(requestConfig);

            HttpResponse response = null;

            response = httpClient.execute(httppost);

            HttpEntity entity = response.getEntity();

            String result = EntityUtils.toString(entity, "UTF-8");

            Map<String,String> resp = Utils.xmlToMap(result);

            String returnCode = resp.get("return_code");

            if("SUCCESS".equals(returnCode))
            {
                String resultCode = resp.get("result_code");

                if("SUCCESS".equals(resultCode))
                {
                    return ValidateUtil.returnSuccess(wxPayRefundReturn);
                }
                else
                {
                    logger.error("微信支付退款失败");

                    String errMsg = resp.get("err_code_des");

                    String errCode = resp.get("err_code");

                    logger.error("ERROR_CODE ："+ errCode + "、ERROR_MSG ：" + errMsg);

                    return ValidateUtil.returnError(CodeEnum.WXPAY_TRADE_REFUND_FAILE.getCode(),CodeEnum.WXPAY_TRADE_REFUND_FAILE.getMessage());
                }
            }
            else
            {
                logger.error("微信支付退款API调用失败");

                String errMsg = resp.get("return_msg");

                logger.error("ERROR_MSG ：" + errMsg);

                return ValidateUtil.returnError(CodeEnum.INVOKE_WXPAY_TRADE_REFUND_FAILE.getCode(),CodeEnum.INVOKE_WXPAY_TRADE_REFUND_FAILE.getMessage());
            }
        }
        catch (Exception e)
        {
            logger.error("微信支付退款执行错误!",e);

            return ValidateUtil.returnError(CodeEnum.WXPAY_TRADE_REFUND_ERROR.getCode(),CodeEnum.WXPAY_TRADE_REFUND_ERROR.getMessage());
        }
    }

    /**
     * 加载证书
     *
     * @param mchId 商户ID
     * @param certPath 证书位置
     * @throws Exception
     */
    private static CloseableHttpClient initCert(String mchId, String certPath) throws Exception
    {
        // 证书密码，默认为商户ID
        String key = mchId;

        // 证书的路径
        String path = certPath;

        // 指定读取证书格式为PKCS12
        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        // 读取本机存放的PKCS12证书文件
//        FileInputStream instream = new FileInputStream(new File(path));
        InputStream instream = WeixinpayServiceImpl.class.getClassLoader().getResourceAsStream(certPath);

        try
        {
            // 指定PKCS12的密码(商户ID)
            keyStore.load(instream, key.toCharArray());

        }
        finally
        {
            instream.close();
        }

        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build();

        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] {"TLSv1"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());

        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

        return httpClient;
    }

//    @Override
//    public void wxAppletPay(String appId, String mchId, String apiKey, String subject, String outTradeNo,String timeExpire, String totalFee, String notifyUrl, String openid)
//    {
//        //返回结果
//        Map<String,Object> resultMap = new HashMap<>();
//
//        resultMap.put("outTradeNo",outTradeNo);
//
//        resultMap.put("timeExpire",timeExpire);
//
//        resultMap.put("totalFee",totalFee);
//
//        resultMap.put("notifyUrl",notifyUrl);
//
//        resultMap.put("openid",openid);
//
//        //设置微信支付配置
//        MyConfig config = new MyConfig();
//
//        config.setApiKey(apiKey);
//
//        config.setAppId(appId);
//
//        config.setMchId(mchId);
//
//        config.setNotifyUrl(notifyUrl);
//
//        try
//        {
//            //初始化微信支付
//            WXPay wxpay = new WXPay(config,"");
//
//            Map<String, String> data = new HashMap<String, String>();
//
//            data.put("body", subject);
//
//            data.put("out_trade_no", outTradeNo);
//
//            data.put("fee_type", "CNY");
//
//            data.put("time_expire", timeExpire);
//
//            BigDecimal totalFeeTmp = BigDecimal.valueOf(0);
//
//            if(totalFee != null && !"".equals(totalFee))
//            {
//                //单位默认为分  *100
//                totalFeeTmp = BigDecimal.valueOf(Double.valueOf(totalFee)).multiply(BigDecimal.valueOf(100));
//            }
//
//            data.put("total_fee", String.valueOf(totalFeeTmp.intValue()));
//
//            data.put("spbill_create_ip", Utils.getServerIp());
//
//            logger.info("当前服务器IP：" + Utils.getServerIp());
//
//            data.put("notify_url", notifyUrl);
//
//            data.put("trade_type", "JSAPI");  // 此处指定为扫码支付
//
//
//            //执行调用 微信下单API
//            Map<String, String> resp = wxpay.unifiedOrder(data);
//
//            String returnCode = resp.get("return_code");
//
//
//            if("SUCCESS".equals(returnCode))
//            {
//                //调用API成功
//                String resultCode = resp.get("result_code");
//
//                if("SUCCESS".equals(resultCode))
//                {
//                    //生成交易订单成功
//                    resultMap.put("trade_type",resp.get("trade_type"));
//
//                    resultMap.put("prepay_id",resp.get("prepay_id"));
//
//                }
//                else
//                {
//                    logger.error("微信小程序下单失败！");
//
//                    String errMsg = resp.get("err_code_des");
//
//                    String errCode = resp.get("err_code");
//
//                    logger.error("ERROR_CODE ："+ errCode + "、ERROR_MSG ：" + errMsg);
//
//                    resultMap.put(CodeConstants.resultcodeKey,CodeConstants.resultcode_0002.resultcode);
//
//                    resultMap.put(CodeConstants.resultmsgKey,CodeConstants.resultcode_0002.resultmsg + errMsg);
//                }
//            }
//            else
//            {
//                logger.error("微信小程序调用下单API失败！");
//
//                String errMsg = resp.get("return_msg");
//
//                logger.error("ERROR_MSG ：" + errMsg);
//
//                resultMap.put(CodeConstants.resultcodeKey,CodeConstants.resultcode_0001.resultcode);
//
//                resultMap.put(CodeConstants.resultmsgKey,CodeConstants.resultcode_0001.resultmsg + errMsg);
//            }
//
//        }
//        catch (Exception e)
//        {
//            logger.error("微信小程序下单错误!",e);
//
//            resultMap.put(CodeConstants.resultcodeKey,CodeConstants.resultcode_0003.resultcode);
//
//            resultMap.put(CodeConstants.resultmsgKey,CodeConstants.resultcode_0003.resultmsg+ e);
//        }
//
//    }

    public static void main(String[] args)
    {
//        URL url = WeixinpayServiceImpl.class.getClassLoader().getResource("static/cert/apiclient_cert.p12");
//
//        System.out.println(url.getPath());

        String path = Thread.currentThread().getContextClassLoader().getResource("static/cert/apiclient_cert.p12").getPath();

        System.out.println(path);
    }


}
